package cn.stimd.spring.aop;

import java.lang.reflect.Method;

/**
 * MethodMatcher是Pointcut的一部分，用于判断目标方法与Advice是否匹配。
 * MethodMatcher分为静态匹配与动态匹配。静态匹配涉及方法及方法属性，
 * 动态匹配还使得参数对于特定调用是可用的，以及应用于该连接点的之前的通知的效果。
 * <p>
 * 如果isRuntime方法返回false，不论什么参数，调用该方法的结果总是相同的。如果返回true，
 * 那么每次在执行相关通知前，都会调用3参数matches方法，以决定是否运行该通知
 * <p>
 * Created by Stimd
 * 项目地址：https://gitee.com/stimd/spring-wheel
 * 公众号：Java编程探微
 */
public interface MethodMatcher {
    MethodMatcher TRUE = new MethodMatcher() {
        @Override
        public boolean matches(Method method, Class<?> targetClass) {
            return true;
        }

        @Override
        public boolean matches(Method method, Class<?> targetClass, Object... args) {
            throw new UnsupportedOperationException();
        }

        @Override
        public boolean isRuntime() {
            return false;
        }
    };

    /**
     * 执行静态检查方法是否匹配，如果返回false或isRuntime返回false，
     * 则不会执行运行时检查，即调用3个参数的matches方法
     */
    boolean matches(Method method, Class<?> targetClass);

    /**
     * 检查指定方法是否存在动态匹配，且该方法必须时静态匹配的。
     * 仅当2参数matches和isRuntime方法都返回true，才会调用该方法
     */
    boolean matches(Method method, Class<?> targetClass, Object... args);

    /**
     * 表示该MethodMatcher是否是动态的。可以在创建Aop代理时调用，无需在每次调用方法前调用
     */
    boolean isRuntime();
}
